<?php
/**
  * tframe
  * 规范插件使用。
  * 基本思想：挂载点，挂载点配置，自动启动插件，
  * 处理输入数据，返回经过转换后的输入数据，获取插件，使用插件的各种功能。
  * 
  * 使用的时候，需要先判断是否存在此插件。
  * 
  *
  * @copyright Copyright (c) 2012 - 2014, huxiaomin
  * @author huxiaomin    2012-6-17  
  * @since		Version 1.0
  *
  */

class TPlugin{
	
	static $plugins = array();
	static $folders = array();
	static $config = array();
	static $Tplugin = '';
	static $getPlugins = array();
	

     function __construct(){
     	if (empty(self::$config)){
         self::$config = include_once TFRAME_DIR.'config/plugin.config.php';
     	}
     	
     }
     
     static function start($point_name,&$request){
        if (empty(self::$Tplugin)){
     	  self::$Tplugin = new TPlugin();
        }
        $mod = self::$Tplugin;
        return $mod->startPoint($point_name,$request);
     }
     
     function startPoint($point_name,&$request){
        $plugins = $this->getPluginByPoint($point_name);
        foreach ((array)$plugins as $plugin_name){
            $plugin = $this->loadPointPlugin($point_name,$plugin_name);
            $plugin->start($request);
        }
     }
     
     function getPluginByPoint($point_name){
     	if (isset(self::$config[$point_name])){
     		return self::$config[$point_name];
     	}else {
     		return array();
     	}
        
     }
     
     function loadPointPlugin($point_name,$plugin_name){
     	if (isset(self::$plugins[$point_name][$plugin_name])){
     	  return self::$plugins[$point_name][$plugin_name];
     	}
     	$load = $this->load($plugin_name);
     	if ($load){
     	  $plugin_class = new $plugin_name($point_name);
     	  self::$plugins[$point_name][$plugin_name] = $plugin_class;
     	  return $plugin_class;
     	  
     	}
     	$str = debug_backtrace();
        $str = $str[1];
     	TLog::logDb("plugin class not exists :{$plugin_name} detail:".json_encode($str),
                                        basename(__FILE__),__CLASS__.'.'.__FUNCTION__,'sys');
     	return false;
     }
     
     /**
      * 不同点的plugin应该有单独的方法。
      * @param $point_name
      * @param $plugin_name
      */
     static function getPlugin($point_name='',$plugin_name){
        if (isset(self::$plugins[$point_name][$plugin_name])){
          return self::$plugins[$point_name][$plugin_name];
        }
        if (empty(self::$Tplugin)){
          self::$Tplugin = new TPlugin();
        }
        $mod = self::$Tplugin;
        $load = $mod->load($plugin_name);
        if ($load){
          $plugin_class = new $plugin_name($point_name);
          self::$getPlugins[$point_name][$plugin_name] = $plugin_class;
          return $plugin_class;
          
        }
        $str = debug_backtrace();
        $str = $str[1];
        TLog::logDb("plugin class not exists :{$plugin_name} detail:".json_encode($str),
                                        basename(__FILE__),__CLASS__.'.'.__FUNCTION__,'sys');
        return false;
     }
     
     function addConfig($conf){
        foreach ((array)$conf as $point=>$v){
            if (!isset(self::$config[$point])){
                self::$config[$point] = array();
            }
            if (!in_array($v,self::$config[$point])){
                self::$config[$point][] = $v;
            }
        }
     }
     
         
     function load($class_name){
        $class_name = substr($class_name,0,-6);
        $dir = TPLUGIN_DIR;
        if (file_exists($dir.$class_name.TPLUGIN_SUFFIX)){
           require_once $dir.$class_name.TPLUGIN_SUFFIX;
           return true;
        }
        else {
           $dirs_arr = self::getFolder($dir);
           foreach ($dirs_arr as $v){
               if (file_exists($v.'/'.$class_name.TPLUGIN_SUFFIX)){
                   require_once $v.'/'.$class_name.TPLUGIN_SUFFIX;
                   return true;
               }
           }
        }
        return false;
        
    }
    
    /**
     * 返回文件夹 
     * @param string $dir
     * @return array
     */
    static function getFolder($dir){
        if (self::$folders){
            return self::$folders;
        }
        
        $TMemcache = new TMemcache();
        $gCacheKey = gCacheKey($dir);
        $cache_value = $TMemcache->get($gCacheKey);
        if ($cache_value){
            self::$folders = $cache_value;
           return $cache_value;
        }
        
        $res = opendir($dir);
        $return = array();
        if (!$res){
            return $return;
        }   
        
        while ($f = readdir($res)){
            if (is_dir($dir.$f) && $f{0} !== '.'){
                $return[] = $dir.$f;
            }
        }
        self::$folders = $return;
        
        $TMemcache->set($gCacheKey,$return,0,3600*24);
        return $return;
    }

}